#ifndef TASK_METADATA_H
#define TASK_METADATA_H
#include <variant>
#include <memory>
#include <vector>
#include "../abc_archive.h"
namespace task
{

    enum class TaskType
    {
        BEFORE_EXECUTION,
        BEFORE_CALL,
        BEFORE_CALLBACK,
        AFTER_EXECUTION,
        AFTER_CALL,
        AFTER_CAllBACK,
        REPLACE_CALL,
        REPLACE_CALLBACK,
        AROUND_EXECUTION,
        AROUND_CALL,
        AROUND_CALLBACK
    };

    struct NodeParam
    {
        std::string module;
        std::string ns;
        std::string klass;
        std::string function;
    };

    enum class PromiseType
    {
        THEN,
        CATCH,
    };

    struct BasicApiInfo
    {
        std::string source;
        std::string objName;
        std::string propName;
    };

    /**
     * 基础的回调api信息，标注回调函数在api的位置，默认首位
     */
    struct BasicCallbackApiInfo : BasicApiInfo
    {
        int idx = 0;
    };
    /**
     * 回调作为对象属性传入的api信息，标注回调函数对应的key
     */
    struct PropCallbackApiInfo : BasicApiInfo
    {
        std::string key;
    };
    /**
     * promise回调，标注回调函数是promise的then或者catch
     */
    struct PromiseApiInfo : BasicApiInfo
    {
        PromiseType promiseType;
    };

    using ApiInfo = std::variant<
        BasicApiInfo *,
        BasicCallbackApiInfo *,
        PropCallbackApiInfo *,
        PromiseApiInfo *>;

    struct TaskParam
    {
        NodeParam *nodeParam;  // module/namespace/class/function 参数配置
        TaskType taskType;     // 插桩任务类型
        ApiInfo *callSite;     // 调用点信息配置
        BasicApiInfo *instApi; // 插桩api信息
    };

    using InstStructType = std::variant<
        AbckitBasicBlock *,
        AbckitInst *>;

} // namespace task

#endif // TASK_METADATA_H
